//! Report Actor
//! 
//! This actor manages test result collection and report generation,
//! corresponding to HttpRunner's Summary system.

use crate::actors::messages::*;
use crate::error::Result;
use crate::models::{
    step::StepResult,
    summary::TestSummary,
    ValueMap,
};
use coerce::actor::Actor;
use coerce::actor::context::ActorContext;
use coerce::actor::message::Handler;
use async_trait::async_trait;
use std::collections::HashMap;

/// Report Actor
#[derive(Debug)]
pub struct ReportActor {
    /// Collected step results
    step_results: Vec<StepResult>,
    
    /// Test statistics
    statistics: ValueMap,
}

impl ReportActor {
    /// Create a new report actor
    pub fn new() -> Self {
        Self {
            step_results: Vec::new(),
            statistics: HashMap::new(),
        }
    }
    
    /// Add step result
    async fn add_step_result(&mut self, result: StepResult) -> Result<ReportResponse> {
        tracing::debug!("Adding step result: {}", result.name);
        
        self.step_results.push(result);
        self.update_statistics().await;
        
        Ok(ReportResponse::StepResultAdded)
    }
    
    /// Generate HTML report
    async fn generate_html_report(
        &self,
        summary: TestSummary,
        output_path: String,
    ) -> Result<ReportResponse> {
        tracing::info!("Generating HTML report: {}", output_path);
        
        // TODO: Implement actual HTML report generation
        
        Ok(ReportResponse::Error {
            message: "HTML report generation not yet implemented".to_string(),
        })
    }
    
    /// Export results
    async fn export_results(
        &self,
        summary: TestSummary,
        format: ExportFormat,
        output_path: String,
    ) -> Result<ReportResponse> {
        tracing::info!("Exporting results in {:?} format: {}", format, output_path);
        
        // TODO: Implement actual result export
        
        Ok(ReportResponse::Error {
            message: "Result export not yet implemented".to_string(),
        })
    }
    
    /// Get test statistics
    async fn get_statistics(&self) -> Result<ReportResponse> {
        Ok(ReportResponse::Statistics {
            stats: self.statistics.clone(),
        })
    }
    
    /// Update statistics based on collected results
    async fn update_statistics(&mut self) {
        let total_steps = self.step_results.len();
        let successful_steps = self.step_results.iter().filter(|r| r.success).count();
        let failed_steps = total_steps - successful_steps;
        
        self.statistics.insert("total_steps".to_string(), serde_json::json!(total_steps));
        self.statistics.insert("successful_steps".to_string(), serde_json::json!(successful_steps));
        self.statistics.insert("failed_steps".to_string(), serde_json::json!(failed_steps));
        
        if total_steps > 0 {
            let success_rate = (successful_steps as f64 / total_steps as f64) * 100.0;
            self.statistics.insert("success_rate".to_string(), serde_json::json!(success_rate));
        }
    }
}

#[async_trait]
impl Actor for ReportActor {
    async fn started(&mut self, _ctx: &mut ActorContext) {
        tracing::info!("ReportActor started");
    }
}

#[async_trait]
impl Handler<ReportMessage> for ReportActor {
    async fn handle(&mut self, msg: ReportMessage, _ctx: &mut ActorContext) -> ReportResponse {
        match msg {
            ReportMessage::AddStepResult { result } => {
                match self.add_step_result(result).await {
                    Ok(response) => response,
                    Err(e) => ReportResponse::Error {
                        message: e.to_string(),
                    },
                }
            }

            ReportMessage::GenerateHTMLReport { summary, output_path } => {
                match self.generate_html_report(summary, output_path).await {
                    Ok(response) => response,
                    Err(e) => ReportResponse::Error {
                        message: e.to_string(),
                    },
                }
            }

            ReportMessage::ExportResults { summary, format, output_path } => {
                match self.export_results(summary, format, output_path).await {
                    Ok(response) => response,
                    Err(e) => ReportResponse::Error {
                        message: e.to_string(),
                    },
                }
            }

            ReportMessage::GetStatistics => {
                match self.get_statistics().await {
                    Ok(response) => response,
                    Err(e) => ReportResponse::Error {
                        message: e.to_string(),
                    },
                }
            }
        }
    }
}
